package com.xwaf.platform.web.config.netty;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.annotation.PreDestroy;
import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
import io.netty.handler.codec.http.websocketx.WebSocketVersion;

/**
 * 
 * <p>
 * WebSocket客户端
 * <p>
 * 
 * @author 李聪 <br>
 * @email xwaf_love@yeah.net <br>
 * @since JDK 1.8<br>
 * @date 2020年1月9日 下午12:30:53 <br>
 * @see 无<br>
 *      Copyright (c) 2020, xwaf_love@yeah.net All Rights Reserved.<br>
 */
@Component
public class WebSocketNettyClient {
	private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketNettyClient.class);

	private Bootstrap bootstrap;
	/**
	 * Work线程组
	 */
	private EventLoopGroup worker;

	/**
	 * 线程池
	 */
	private ExecutorService executorService = Executors.newFixedThreadPool(3);

	/**
	 * WebSocket客户端配置类
	 */
	@Resource
	private WebSocketNettyClientConfig webSocketNettyConfig;

	public WebSocketNettyClient() {
		bootstrap = new Bootstrap();
		worker = new NioEventLoopGroup();
		bootstrap.group(worker);
		bootstrap.channel(NioSocketChannel.class);
	}

	public void run(String host, int port) {
		executorService.submit(() -> {
			// 配置客户端的NIO线程组
			EventLoopGroup clientGroup = new NioEventLoopGroup();
			try {
				WebSocketNettyClientHandler webSocketClientHandler = new WebSocketNettyClientHandler(
						WebSocketClientHandshakerFactory.newHandshaker(
								new URI("ws://" + webSocketNettyConfig.getHost() + ":" + webSocketNettyConfig.getPort()
										+ "/" + webSocketNettyConfig.getUrl() + "/"
										+ webSocketNettyConfig.getUserName()),
								WebSocketVersion.V13, null, false, new DefaultHttpHeaders()));
				// 配置bootstrap
				bootstrap.handler(new WebSocketNettyHandlerClient(webSocketClientHandler));
				// 发起异步连接操作 同步方法待成功
				Channel channel = bootstrap.connect(host, port).sync().channel();
				// 等待客户端链路关闭
				channel.closeFuture().sync();
			} catch (InterruptedException | URISyntaxException e) {
				e.printStackTrace();
			} finally {
				// 优雅退出，释放NIO线程组
				clientGroup.shutdownGracefully();
			}
		});
	}

	/**
	 * 关闭与netty服务器的连接
	 */
	@PreDestroy
	public void close() {
		LOGGER.info("├ [关闭链接]");
		worker.shutdownGracefully();
	}
}